/*
 * Copyright 2010 WANdisco, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */
package com.googlecode.svnj;

import java.io.File;
import java.io.OutputStreamWriter;
import java.io.Writer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.svnj.reports.Depth;
import com.googlecode.svnj.reports.UpdateReport;
import com.googlecode.svnj.reports.XMLDeltaEditor;

public class EditorDriver {

    private static final Logger log = LoggerFactory.getLogger(EditorDriver.class);
    
    private IDeltaEditor editor;
    // native ptr - don't f**k with this!
    private long ptr;
    private long endRev;
    RepoContext ctx;
    
    public EditorDriver(IDeltaEditor editor, RepoContext ctx,
            String subpath, long startRev, long endRev) {
        this(editor, ctx, new UpdateReport(subpath, startRev, endRev));
    }
    
    public EditorDriver(IDeltaEditor editor, RepoContext ctx, UpdateReport ur) {
        this.editor = editor;
        this.endRev = ur.getTargetRevision();
        this.ctx = ctx;
        initSelf(endRev, ctx.getRepoDir());
        //if (log.isDebugEnabled()) {
            log.info("beginReport('" + ur.getSrcPath() + "', '" + ur.getUpdateTarget() + "', '"
                    + ur.getDstPath() + ", txdeltas=" + ur.isTextDeltas() + "', depth=" + ur.getDepth()
                    + ", ignoreAncestry=" + ur.isIgnoreAncestry() + ", sendCopyArgs=" + ur.isSendCopyFromArgs() + ")");
        //}
        beginReport(
                ur.getSrcPath(), ur.getUpdateTarget(), ur.getDstPath(),
                ur.isTextDeltas(), ur.getDepth().getValue(),
                ur.isIgnoreAncestry(), ur.isSendCopyFromArgs()
                );
        for (UpdateReport.Entry e : ur.getEntries()) {
            addPathEntry(e);
        }
    }
    
    /** close file descriptors, and free memory */
    public native void cleanupSelf();
    /** analogous to svn_repos_finish_report() */
    public native void startEdit();
    /** analogous to svn_repos_begin_report2() */
    private native void beginReport(String fs_base,
            String target, String tgt_path, boolean text_deltas,
            int depth, boolean ignore_ancestry, boolean send_copyfrom_args);

    private native void addPath(String path, String linkpath, long rev, int depth,
            boolean startEmpty, String locktoken);

    public void addPathEntry(UpdateReport.Entry e) {
        addPath(e.getPath(), e.getLinkPath(), e.getRev(),
                e.getDepth(), e.isStartEmpty(), e.getLockToken());
    }
    /** analogous to svn_repos_set_path3()/svn_repos_link_path3() */ 
    public void addPath(String path, String linkpath, long rev, Depth d,
                boolean startEmpty, String locktoken) {
        log.info("addPath(path='" + path + "', linkpath='" + linkpath
                + "', rev=" + rev + ", depth=" + d + ", start_empty=" + startEmpty
                + ", lock=" + locktoken + ")");
        addPath(path, linkpath, rev, d.getValue(), startEmpty, locktoken);
    }
    static {
        System.loadLibrary("svnj");
        initFields();
    }

    public static void main(String[] a) throws Exception {
        IDeltaEditor ed;
        ed = new NOOPDeltaEditor();
        RepoContext ctx = new RepoContext(new File("/home/dave/tmp/repo/alphabet"), "/svnj/alphabet");
        
        String root = "A/D/H";
        root = "";
        for (long start = 7; start < 8; start++) {
            long end = start + 1;
            ed = new XMLDeltaEditor(System.out, ctx);
            System.out.println("-----running " + start + "->" + end + "-----------");
            EditorDriver drv = new EditorDriver(ed, ctx, "/", start, end);
            try {
                drv.startEdit();
            } catch (Exception e) {
                System.err.println("caught exception in main: " + e);
                e.printStackTrace();
                break;
            } finally {
                drv.cleanupSelf();
                System.out.println("[EditorDriver] post cleanup, ptr is " + drv.ptr);
                System.out.println("-------- ran " + start + "->" + end + "--------");
            }
        }
    }

    private static native void initFields();
    private native void initSelf(long endRev, String reposDir);

}
